MSE(Media Source Extensions)的一点尝试

您所在的位置:网站首页 media source翻译 MSE(Media Source Extensions)的一点尝试

MSE(Media Source Extensions)的一点尝试

2023-06-29 04:33| 来源: 网络整理| 查看: 265

最近对于blob这个东西真的是很感兴趣,图片可以是blob,视频可以是blob,直播也可以是blob,感觉很厉害啊。与之紧密联系的MSE(Media Source Extensions)这个概念。研究一波。

Media Source Extensions 允许JavaScript动态地为和创建媒体流,而不再只能是引用一个视频文件的url。这样就极大地丰富了前端对音视频的处理能力,也赋予了其更多灵活性。

从实例上手

我们先从一个普通的mp4的播放形式上进行改造,由文件url的形式改为blob的方式,以加深对MSE的一点理解。

前端部分

代码不多,大概是这样子。注释中大概解释了基本的流程。 // MediaSource的readyState属性表示了其状态,分别有closed,open,ended三种 // closed:MS没有和媒体元素如video相关联。MS刚创建时就是该状态。 // open:source打开,并且准备接受通过sourceBuffer.appendBuffer添加的数据。 // ended:当endOfStream()执行完成,会变为该状态。

export default { data() { return { mediaSource: null, sourceBuffer: null, mimeType: 'video/mp4;codecs="avc1.42E01E,mp4a.40.2"' } }, mounted() { // MediaSource.isTypeSupported('video/webm;codecs="vorbis,vp8"');//是否支持webm // MediaSource.isTypeSupported('video/mp4;codecs="avc1.42E01E,mp4a.40.2"')//是否支持MP4 // MediaSource.isTypeSupported('video/mp2t;codes="avc1.42E01E,mp4a.40.2"')//是否支持ts // 首先判断一下对视频格式的支持度,MediaSource提供了isTypeSupported方法 if ('MediaSource' in window && MediaSource.isTypeSupported(this.mimeType)) { this.createMediaSource() } else { this.$message({message: '您的浏览器不支持MediaSource', type: 'warning'}) } }, methods: { createMediaSource() { // 创建MediaSource对象,并使用URL.createObjectURL来创建指向MediaSource对象的URL供video播放 this.mediaSource = new MediaSource() this.$refs.h5video.src = window.URL.createObjectURL(this.mediaSource) // 监听sourceopen this.mediaSource.addEventListener('sourceopen', this.onSourceOpen) }, onSourceOpen() { let self = this // 创建一个新的 SourceBuffer 对象,然后会将它追加到 MediaSource 的 SourceBuffers 列表中。 this.sourceBuffer = this.mediaSource.addSourceBuffer(this.mimeType) // 监听buffer更新结束事件 this.sourceBuffer.addEventListener('updateend', () => { // 停止stream self.mediaSource.endOfStream() // 开始播放 self.$refs.h5video.play() }) this.requestBuffer() }, requestBuffer() { let self = this // 请求接口去拉流 this.$http.get('GetStream', null, {responseType: 'arraybuffer'}).then(resp => { // 拉到的流塞进sourceBuffer里。 self.sourceBuffer.appendBuffer(resp) }) } } } 后端服务

后端服务主要是将一个视频文件以流的形式推给前端。

router.get('/GetStream', function(req, res, next) { let filePath = 'public/videos/frag_bunny.mp4' res.set('Content-Type', 'application/octet-stream'); fs.createReadStream(filePath).pipe(res) })

遇到的坑是:一开始用的是自己本地随便找的一个视频文件,结果报错:

Uncaught DOMException: Failed to execute ‘endOfStream’ on ‘MediaSource’: The MediaSource’s readyState is not ‘open’.

原因是该MP4文件不是 fragmented mp4,不支持这种MSE的播放形式。最后在MDN上找了一个可用的MP4。

这里也提供一个转换的工具,支持将普通MP4转为 fragmented mp4

Bento4 MP4 & DASH Class Library, SDK and Tools

最后可以看到前端的video已经是用blob在播放了。

blob播放



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3